<?php
namespace core\models;
/**
 * 控制器抽象类
 * @author ZhouHaoHua <53027327@qq.com>
 */
abstract class Abstract_Action {
    /**
     * 模板中要用到的数据
     * @var array
     */
    public $data = array();
    /**
     * 是否启用页面缓存
     * @var bool
     */
    public $USE_PAGE_CACHE = false;
    /**
     * 当前控制器名称
     * @var string
     */
    public $mod;
    /**
     * 网页主框架页，它的内容包括了html,head,title,meta,body等节点
     * @var string
     */
    public $tplMainPage = 'MainPage/html5.tpl.php';
    /**
     * 网页头部的模板文件名。如：top.tpl.php, top/2015.tpl.php或top.html，支持views目录下面的相对路径
     * @var string
     */
    public $tplTop = '';
    /**
     * 网页中部模板文件名。如：index.tpl.php, index/list.tpl.php，支持views目录下面的相对路径
     * @var string
     */
    public $tplContent = '';
    /**
     * 网页底部的模板文件名。如：Bottom.tpl.php, Bottom/2015.tpl.php或bottom.html，支持views目录下面的相对路径
     * @var string
     */
    public $tplBottom = '';
    /**
     * 网页body部分的扩展内容，如：<body class="ca" style="overflow:hidden"> 中的class="ca" style="overflow:hidden"就是扩展的内容
     * @var string
     */
    public $tplBodyExt = '';
    /**
     * 当前页面控制器是否需要启用session会话功能。默认设置为false，此项若要打开可以到具体的控制器中在【类初始化的时候】设置比较节约服务器响应时间。如在注册、登录购买过程等设置为true！
     * @var bool true为启用，false为不启用
     */
    public $sessionUse = true;
    /**
     * session的保存类型, Memcache 或 System。配置文件可设置
     * @var string
     */
    public $sessionSaveType = 'Memcache';
    /**
     * session会话名称。配置文件可设置
     * @var string
     */
    public $sessionName = 'ZfOsCid';
    /**
     * session的生命周期(秒)。配置文件可设置
     * @var int
     */
    public $sessionLifeTime = 1440;
    /**
     * 以system方式保存时session的保存文件路径。配置文件可设置
     * @var string
     */
    public $sessionSaveDir = Z_SESSION_DIR;
    /**
     * Cookie根目录。配置文件可设置
     * @var string
     */
    public $cookiePath = '/';
    /**
     * Cookie的作用域范围，如：.test.com
     * @var string
     */
    public $cookieDomain = '';

    /**
     * 初始化
     */
    public function __construct() {
        //把配置文件的内容写入来
        $C = new \config();//Z_ENV 原来传到CONFIG的常理，移到CONFIG里面去了，不再传 by lwkai added 2016-7-8
        $cw                    = $C->web();
        $this->sessionSaveType = ($cw::SESSION_SAVE_TYPE ? $cw::SESSION_SAVE_TYPE : $this->sessionSaveType);
        $this->sessionSaveDir  = ($cw::SESSION_SAVE_DIR ? $cw::SESSION_SAVE_DIR : $this->sessionSaveDir);
        $this->sessionName     = ($cw::SESSION_NAME ? $cw::SESSION_NAME : $this->sessionName);
        $this->sessionLifeTime = ($cw::SESSION_LIFE_TIME ? $cw::SESSION_LIFE_TIME : $this->sessionLifeTime);
        $this->cookiePath      = ($cw::COOKIE_PATH ? $cw::COOKIE_PATH : $this->cookiePath);
        $this->cookieDomain    = ($cw::COOKIE_DOMAIN ? $cw::COOKIE_DOMAIN : $this->cookieDomain);


        //include Z_DIR . '/core/config/config.php';
        //过滤GET和POST变量安全输出
        if ($C->web()->filterGetPost) {
            if(Z_MAGIC_QUOTES_GPC !== true) {
                if (!empty($_GET)) {
                    $_GET = \Z::Arrays()->htmlspecialchars($_GET, ENT_QUOTES, Z_CHARSET_PROJECT);
                }
                if (!empty($_POST)) {
                    $_POST = \Z::Arrays()->htmlspecialchars($_POST, ENT_QUOTES, Z_CHARSET_PROJECT);
                }
                if (!empty($_REQUEST)) {
                    $_REQUEST = \Z::Arrays()->htmlspecialchars($_REQUEST, ENT_QUOTES, Z_CHARSET_PROJECT);
                }
            }
            //print_r($_REQUEST);exit;
        }
    }
    /**
     * 二级初始化，它排在__construct后面执行
     */
    public function __init(){}
    /**
     * 捕捉进程与当前uri路径
     */
    protected function getPid() {
        return; //当发现PHP进程CPU占用率高时可以打开记录把PID记录下来，方便查找问题！
        $PIDS = array('41999', '41963'); //要捕捉的进程
        $pid  = posix_getpid();
        if (in_array($pid, $PIDS)) {
            $uri  = $_SERVER['REQUEST_URI'];
            $data = 'PID:' . $pid . "\n";
            $data .= 'URI:' . $uri . "\n";
            $data .= 'IP:' . Others::get_client_ip();
            $data .= "\n";
            file_put_contents(Z_DIR . '/tmp/PID.log', $data, FILE_APPEND);
        }
    }

    /**
     * 当遇到不存在的方法的处理方式
     * @param string $name      方法名称
     * @param array  $arguments 参数列表
     * @throws \ErrorException
     */
    public function __call($name, $arguments) {
        $txt = "不存在的方法： '$name' 参数：" . implode(', ', $arguments) . "\n";
        //throw \Z::Error(\Z::Strings()->stringToHtmlEntitiles($txt, 'utf-8'));
        \Z::Html()->redirect(\Z::Html()->href_link('page404.php','actionError=1&errorText='.$txt.'&referer=' . $_SERVER['REQUEST_URI']));
    }

    /**
     * 析构处理
     */
    public function __destruct() { }

    /**
     * 获取$_GET或者$_POST中的数据
     * @param string $name 要获取的参数名称
     * @param object|string  $callback  可以传自定义的回调，也可以传系统函数，还有自定义的 ['a,a'=>'表示处理多个用逗号分隔的ID'],不传则直接获取值回来
     * @param string $default  默认值
     * @return mixed|string
     * @author 李文凯 <1275124829@163.com>
     * @date   2020-10-17
     */
    protected function _input($name,$callback = '',$default = ''){
        $field = isset($_REQUEST[$name]) ? $_REQUEST[$name] : '';
        return $field !== '' ? $this->checkParamsStr($field,$callback) : $default;
    }

    /**
     * 获取$_GET中的数据
     * @param string $name 要获取的参数名称
     * @param object|string  $callback  可以传自定义的回调，也可以传系统函数，还有自定义的 ['a,a'=>'表示处理多个用逗号分隔的ID'],不传则直接获取值回来
     * @param string $default  默认值
     * @return mixed|string
     * @author 李文凯 <1275124829@163.com>
     * @date   2020-10-17
     */
    protected function _get($name,$callback = '',$default = ''){
        $field = isset($_GET[$name]) ? $_GET[$name] : '';
        return $field !== '' ? $this->checkParamsStr($field,$callback) : $default;
    }

    /**
     * 获取$_POST中的数据
     * @param string $name 要获取的参数名称
     * @param object|string  $callback  可以传自定义的回调，也可以传系统函数，还有自定义的 ['a,a'=>'表示处理多个用逗号分隔的ID'],不传则直接获取值回来
     * @param string $default  默认值
     * @return mixed|string
     * @author 李文凯 <1275124829@163.com>
     * @date   2020-10-17
     */
    protected function _post($name,$callback = '',$default = '') {
        $field = isset($_POST[$name]) ? $_POST[$name] : '';
        return $field !== '' ? $this->checkParamsStr($field,$callback) : $default;
    }

    private function checkParamsStr($field,$callback){
        if ($field !== '') {
            if (is_string($callback)) {
                switch (strtolower($callback)) {
                    case 'a,a':
                        $field = $this->clearArr($field);
                        break;
                    default:
                        if (is_callable($callback)) {
                            $field = $callback($field);
                        }
                }
            } elseif (is_callable($callback)) {
                $field = $callback($field);
            }
            return $field;
        }
        return '';
    }


    /**
     * 格式化 1,2,3,4,5 这种情况的字符串为数组，并且把值转为整型
     * @param string $ids 要格式化的字符串
     * @return array
     * @author 李文凯 <1275124829@163.com>
     * @date   2020-10-17
     */
    private function clearArr($ids){
        if ($ids) {
            $ids = explode(',', $ids);
            $rtn = [];
            foreach ($ids as $k => $v) {
                if (intval($v)) {
                    $rtn[] = intval($v);
                }
            }
            return $rtn;
        }
        return [];
    }
}
